import 'dart:convert';
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';

/// 网络请求工具类
/// 基于Dio封装，支持GET/POST请求、拦截器、自定义请求头等功能
class HttpClient {
  static HttpClient? _instance;
  late Dio _dio;
  
  // 单例模式
  static HttpClient get instance {
    _instance ??= HttpClient._internal();
    return _instance!;
  }
  
  HttpClient._internal() {
    _initDio();
  }
  
  /// 初始化Dio配置
  void _initDio() {
    _dio = Dio();
    
    // 基础配置
    _dio.options = BaseOptions(
      baseUrl: '', // 可以设置基础URL
      connectTimeout: const Duration(seconds: 30),
      receiveTimeout: const Duration(seconds: 30),
      sendTimeout: const Duration(seconds: 30),
      headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json',
      },
    );
    
    // 添加拦截器
    _addInterceptors();
  }
  
  /// 添加拦截器
  void _addInterceptors() {
    // 请求拦截器
    _dio.interceptors.add(
      InterceptorsWrapper(
        onRequest: (options, handler) {
          // 在请求发送前可以添加通用处理
          if (kDebugMode) {
            print('🚀 请求: ${options.method} ${options.uri}');
            print('📤 请求头: ${options.headers}');
            if (options.data != null) {
              print('📦 请求数据: ${options.data}');
            }
          }
          handler.next(options);
        },
        onResponse: (response, handler) {
          // 响应拦截器
          if (kDebugMode) {
            print('✅ 响应: ${response.statusCode} ${response.requestOptions.uri}');
            print('📥 响应数据: ${response.data}');
          }
          handler.next(response);
        },
        onError: (error, handler) {
          // 错误拦截器
          if (kDebugMode) {
            print('❌ 请求错误: ${error.message}');
            print('🔗 请求地址: ${error.requestOptions.uri}');
          }
          handler.next(error);
        },
      ),
    );
    
    // 日志拦截器（仅在调试模式下）
    if (kDebugMode) {
      _dio.interceptors.add(LogInterceptor(
        requestBody: true,
        responseBody: true,
        requestHeader: true,
        responseHeader: false,
        error: true,
      ));
    }
  }
  
  /// 设置基础URL
  void setBaseUrl(String baseUrl) {
    _dio.options.baseUrl = baseUrl;
  }
  
  /// 设置通用请求头
  void setHeaders(Map<String, dynamic> headers) {
    _dio.options.headers.addAll(headers);
  }
  
  /// 添加单个请求头
  void addHeader(String key, dynamic value) {
    _dio.options.headers[key] = value;
  }
  
  /// 移除请求头
  void removeHeader(String key) {
    _dio.options.headers.remove(key);
  }
  
  /// 设置Token
  void setToken(String token) {
    _dio.options.headers['Authorization'] = 'Bearer $token';
  }
  
  /// 清除Token
  void clearToken() {
    _dio.options.headers.remove('Authorization');
  }

  /// 通用请求方法 - 简化版
  /// [path] 接口路径（不包含host地址）
  /// [method] 请求方法 GET/POST/PUT/DELETE
  /// [params] 请求参数Map
  /// [headers] 自定义请求头
  Future<HttpResponse> request(
    String path, {
    String method = 'GET',
    Map<String, dynamic>? params,
    Map<String, dynamic>? headers,
  }) async {
    try {
      Response response;
      final options = _mergeOptions(null, headers);
      
      switch (method.toUpperCase()) {
        case 'GET':
          response = await _dio.get(
            path,
            queryParameters: params,
            options: options,
          );
          break;
        case 'POST':
          response = await _dio.post(
            path,
            data: params,
            options: options,
          );
          break;
        case 'PUT':
          response = await _dio.put(
            path,
            data: params,
            options: options,
          );
          break;
        case 'DELETE':
          response = await _dio.delete(
            path,
            data: params,
            options: options,
          );
          break;
        default:
          throw ArgumentError('不支持的请求方法: $method');
      }
      
      return _handleResponse(response);
    } catch (e) {
      return _handleError(e);
    }
  }

  /// 通用请求方法 - 回调版本
  /// [path] 接口路径（不包含host地址）
  /// [method] 请求方法 GET/POST/PUT/DELETE
  /// [params] 请求参数Map
  /// [headers] 自定义请求头
  /// [onSuccess] 成功回调
  /// [onError] 失败回调
  void requestWithCallback(
    String path, {
    String method = 'GET',
    Map<String, dynamic>? params,
    Map<String, dynamic>? headers,
    Function(HttpResponse response)? onSuccess,
    Function(HttpResponse error)? onError,
  }) async {
    try {
      Response response;
      final options = _mergeOptions(null, headers);
      
      switch (method.toUpperCase()) {
        case 'GET':
          response = await _dio.get(
            path,
            queryParameters: params,
            options: options,
          );
          break;
        case 'POST':
          response = await _dio.post(
            path,
            data: params,
            options: options,
          );
          break;
        case 'PUT':
          response = await _dio.put(
            path,
            data: params,
            options: options,
          );
          break;
        case 'DELETE':
          response = await _dio.delete(
            path,
            data: params,
            options: options,
          );
          break;
        default:
          if (onError != null) {
            onError(_handleError(ArgumentError('不支持的请求方法: $method')));
          }
          return;
      }
      
      final result = _handleResponse(response);
      if (result.success && onSuccess != null) {
        onSuccess(result);
      } else if (!result.success && onError != null) {
        onError(result);
      }
    } catch (e) {
      if (onError != null) {
        onError(_handleError(e));
      }
    }
  }

  /// GET请求 - 简化版
  /// [path] 接口路径（不包含host地址）
  /// [params] 查询参数Map
  /// [headers] 自定义请求头
  Future<HttpResponse> simpleGet(
    String path, {
    Map<String, dynamic>? params,
    Map<String, dynamic>? headers,
  }) async {
    return request(path, method: 'GET', params: params, headers: headers);
  }

  /// POST请求 - 简化版
  /// [path] 接口路径（不包含host地址）
  /// [params] 请求参数Map
  /// [headers] 自定义请求头
  Future<HttpResponse> simplePost(
    String path, {
    Map<String, dynamic>? params,
    Map<String, dynamic>? headers,
  }) async {
    return request(path, method: 'POST', params: params, headers: headers);
  }

  /// PUT请求 - 简化版
  /// [path] 接口路径（不包含host地址）
  /// [params] 请求参数Map
  /// [headers] 自定义请求头
  Future<HttpResponse> simplePut(
    String path, {
    Map<String, dynamic>? params,
    Map<String, dynamic>? headers,
  }) async {
    return request(path, method: 'PUT', params: params, headers: headers);
  }

  /// DELETE请求 - 简化版
  /// [path] 接口路径（不包含host地址）
  /// [params] 请求参数Map
  /// [headers] 自定义请求头
  Future<HttpResponse> simpleDelete(
    String path, {
    Map<String, dynamic>? params,
    Map<String, dynamic>? headers,
  }) async {
    return request(path, method: 'DELETE', params: params, headers: headers);
  }

  // ==================== 回调版本的简化方法 ====================

  /// GET请求 - 回调版
  /// [path] 接口路径（不包含host地址）
  /// [params] 查询参数Map
  /// [headers] 自定义请求头
  /// [onSuccess] 成功回调
  /// [onError] 失败回调
  void simpleGetWithCallback(
    String path, {
    Map<String, dynamic>? params,
    Map<String, dynamic>? headers,
    Function(HttpResponse response)? onSuccess,
    Function(HttpResponse error)? onError,
  }) {
    requestWithCallback(
      path,
      method: 'GET',
      params: params,
      headers: headers,
      onSuccess: onSuccess,
      onError: onError,
    );
  }

  /// POST请求 - 回调版
  /// [path] 接口路径（不包含host地址）
  /// [params] 请求参数Map
  /// [headers] 自定义请求头
  /// [onSuccess] 成功回调
  /// [onError] 失败回调
  void simplePostWithCallback(
    String path, {
    Map<String, dynamic>? params,
    Map<String, dynamic>? headers,
    Function(HttpResponse response)? onSuccess,
    Function(HttpResponse error)? onError,
  }) {
    requestWithCallback(
      path,
      method: 'POST',
      params: params,
      headers: headers,
      onSuccess: onSuccess,
      onError: onError,
    );
  }

  /// PUT请求 - 回调版
  /// [path] 接口路径（不包含host地址）
  /// [params] 请求参数Map
  /// [headers] 自定义请求头
  /// [onSuccess] 成功回调
  /// [onError] 失败回调
  void simplePutWithCallback(
    String path, {
    Map<String, dynamic>? params,
    Map<String, dynamic>? headers,
    Function(HttpResponse response)? onSuccess,
    Function(HttpResponse error)? onError,
  }) {
    requestWithCallback(
      path,
      method: 'PUT',
      params: params,
      headers: headers,
      onSuccess: onSuccess,
      onError: onError,
    );
  }

  /// DELETE请求 - 回调版
  /// [path] 接口路径（不包含host地址）
  /// [params] 请求参数Map
  /// [headers] 自定义请求头
  /// [onSuccess] 成功回调
  /// [onError] 失败回调
  void simpleDeleteWithCallback(
    String path, {
    Map<String, dynamic>? params,
    Map<String, dynamic>? headers,
    Function(HttpResponse response)? onSuccess,
    Function(HttpResponse error)? onError,
  }) {
    requestWithCallback(
      path,
      method: 'DELETE',
      params: params,
      headers: headers,
      onSuccess: onSuccess,
      onError: onError,
    );
  }
  
  /// GET请求
  /// [url] 请求地址
  /// [queryParameters] 查询参数
  /// [options] 请求配置
  /// [headers] 自定义请求头
  Future<HttpResponse> get(
    String url, {
    Map<String, dynamic>? queryParameters,
    Options? options,
    Map<String, dynamic>? headers,
  }) async {
    try {
      final response = await _dio.get(
        url,
        queryParameters: queryParameters,
        options: _mergeOptions(options, headers),
      );
      return _handleResponse(response);
    } catch (e) {
      return _handleError(e);
    }
  }
  
  /// POST请求
  /// [url] 请求地址
  /// [data] 请求数据
  /// [queryParameters] 查询参数
  /// [options] 请求配置
  /// [headers] 自定义请求头
  Future<HttpResponse> post(
    String url, {
    dynamic data,
    Map<String, dynamic>? queryParameters,
    Options? options,
    Map<String, dynamic>? headers,
  }) async {
    try {
      final response = await _dio.post(
        url,
        data: data,
        queryParameters: queryParameters,
        options: _mergeOptions(options, headers),
      );
      return _handleResponse(response);
    } catch (e) {
      return _handleError(e);
    }
  }
  
  /// PUT请求
  Future<HttpResponse> put(
    String url, {
    dynamic data,
    Map<String, dynamic>? queryParameters,
    Options? options,
    Map<String, dynamic>? headers,
  }) async {
    try {
      final response = await _dio.put(
        url,
        data: data,
        queryParameters: queryParameters,
        options: _mergeOptions(options, headers),
      );
      return _handleResponse(response);
    } catch (e) {
      return _handleError(e);
    }
  }
  
  /// DELETE请求
  Future<HttpResponse> delete(
    String url, {
    dynamic data,
    Map<String, dynamic>? queryParameters,
    Options? options,
    Map<String, dynamic>? headers,
  }) async {
    try {
      final response = await _dio.delete(
        url,
        data: data,
        queryParameters: queryParameters,
        options: _mergeOptions(options, headers),
      );
      return _handleResponse(response);
    } catch (e) {
      return _handleError(e);
    }
  }
  
  /// 文件上传
  Future<HttpResponse> upload(
    String url,
    String filePath, {
    String? fileName,
    Map<String, dynamic>? data,
    Map<String, dynamic>? headers,
    ProgressCallback? onSendProgress,
  }) async {
    try {
      final formData = FormData.fromMap({
        ...?data,
        'file': await MultipartFile.fromFile(
          filePath,
          filename: fileName,
        ),
      });
      
      final response = await _dio.post(
        url,
        data: formData,
        options: _mergeOptions(null, headers),
        onSendProgress: onSendProgress,
      );
      return _handleResponse(response);
    } catch (e) {
      return _handleError(e);
    }
  }
  
  /// 文件下载
  Future<HttpResponse> download(
    String url,
    String savePath, {
    Map<String, dynamic>? queryParameters,
    Map<String, dynamic>? headers,
    ProgressCallback? onReceiveProgress,
  }) async {
    try {
      final response = await _dio.download(
        url,
        savePath,
        queryParameters: queryParameters,
        options: _mergeOptions(null, headers),
        onReceiveProgress: onReceiveProgress,
      );
      return _handleResponse(response);
    } catch (e) {
      return _handleError(e);
    }
  }
  
  /// 合并请求配置
  Options? _mergeOptions(Options? options, Map<String, dynamic>? headers) {
    if (headers == null) return options;
    
    if (options == null) {
      return Options(headers: headers);
    } else {
      return options.copyWith(
        headers: {...?options.headers, ...headers},
      );
    }
  }
  
  /// 处理响应数据
  HttpResponse _handleResponse(Response response) {
    Map<String, dynamic> jsonData = {};
    
    // 尝试将响应数据转换为JSON
    try {
      if (response.data is String) {
        jsonData = json.decode(response.data);
      } else if (response.data is Map) {
        jsonData = Map<String, dynamic>.from(response.data);
      } else {
        jsonData = {'data': response.data};
      }
    } catch (e) {
      jsonData = {
        'error': '数据解析失败',
        'raw_data': response.data.toString(),
      };
    }
    
    // HTTP请求成功(状态码200)
    bool httpSuccess = response.statusCode == 200;
    
    // 业务成功判断(响应数据中的code字段为200)
    bool businessSuccess = httpSuccess && 
        jsonData.containsKey('code') && 
        jsonData['code'] == 200;
    
    // 获取业务消息
    String businessMessage = '';
    if (jsonData.containsKey('message')) {
      businessMessage = jsonData['message']?.toString() ?? '';
    } else if (jsonData.containsKey('msg')) {
      businessMessage = jsonData['msg']?.toString() ?? '';
    }
    
    return HttpResponse(
      success: businessSuccess, // 业务成功
      httpSuccess: httpSuccess, // HTTP请求成功
      statusCode: response.statusCode ?? 0,
      message: businessMessage.isNotEmpty ? businessMessage : (response.statusMessage ?? ''),
      data: jsonData,
      headers: response.headers.map,
    );
  }
  
  /// 处理错误
  HttpResponse _handleError(dynamic error) {
    String message = '请求失败';
    int statusCode = 0;
    Map<String, dynamic> data = {};
    
    if (error is DioException) {
      statusCode = error.response?.statusCode ?? 0;
      
      switch (error.type) {
        case DioExceptionType.connectionTimeout:
          message = '连接超时，请检查网络连接';
          break;
        case DioExceptionType.sendTimeout:
          message = '请求发送超时，请稍后重试';
          break;
        case DioExceptionType.receiveTimeout:
          message = '响应接收超时，请稍后重试';
          break;
        case DioExceptionType.badResponse:
          message = '服务器响应错误: ${error.response?.statusCode}';
          if (error.response?.data != null) {
            try {
              if (error.response!.data is String) {
                data = json.decode(error.response!.data);
              } else if (error.response!.data is Map) {
                data = Map<String, dynamic>.from(error.response!.data);
              }
            } catch (e) {
              data = {'error_data': error.response!.data.toString()};
            }
          }
          break;
        case DioExceptionType.cancel:
          message = '请求已取消';
          break;
        case DioExceptionType.connectionError:
          message = '网络连接错误，请检查网络设置';
          break;
        case DioExceptionType.badCertificate:
          message = 'SSL证书验证失败，请检查网络安全设置';
          break;
        case DioExceptionType.unknown:
          message = '未知网络错误: ${error.message}';
          break;
      }
    } else {
      message = error.toString();
    }
    
   return HttpResponse(
      success: false, // 业务失败
      httpSuccess: false, // HTTP请求失败
      statusCode: statusCode,
      message: message,
      data: data,
      headers: {},
    );
  }
}

/// HTTP响应封装类
class HttpResponse {
  /// 业务是否成功(基于业务code判断)
  final bool success;
  
  /// HTTP请求是否成功(基于HTTP状态码判断)
  final bool httpSuccess;
  
  /// HTTP状态码
  final int statusCode;
  
  /// 响应消息
  final String message;
  
  /// 响应数据
  final Map<String, dynamic> data;
  
  /// 响应头
  final Map<String, List<String>> headers;
  
  const HttpResponse({
    required this.success,
    required this.httpSuccess,
    required this.statusCode,
    required this.message,
    required this.data,
    required this.headers,
  });
  
  /// 判断业务是否成功
  bool get isBusinessSuccess {
    // 业务成功需要同时满足：HTTP请求成功 && 业务code为200
    return httpSuccess && data.containsKey('code') && data['code'] == 200;
  }
  
  /// 获取业务状态码
  int get businessCode {
    return data['code'] ?? -1;
  }
  
  /// 获取业务数据
  T? getBusinessData<T>([String key = 'data']) {
    if (!success || !data.containsKey(key)) return null;
    return data[key] as T?;
  }
  
  /// 获取业务消息
  String getBusinessMessage([String key = 'message']) {
    if (data.containsKey(key)) {
      return data[key]?.toString() ?? message;
    }
    return message;
  }
  
  @override
  String toString() {
    return 'HttpResponse{success: $success, httpSuccess: $httpSuccess, statusCode: $statusCode, businessCode: $businessCode, message: $message, data: $data}';
  }
}